package com.example.dayu521.sg_oss.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.dayu521.sg_oss.domain.Trade;
import com.example.dayu521.sg_oss.mapper.TradeMapper;
import com.example.dayu521.sg_oss.service.TradeService;
import io.seata.rm.tcc.api.BusinessActionContextParameter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;

/**
 * @author hasee
 * @description 针对表【t_trade】的数据库操作Service实现
 * @createDate 2023-09-04 15:40:43
 */
@Service
@Slf4j
public class TradeServiceImpl extends ServiceImpl<TradeMapper, Trade>
        implements TradeService {

    @Override
    public boolean save(@BusinessActionContextParameter(paramName = "params")Trade entity) {
        return super.save(entity);
    }

    //2.0.0 bug https://github.com/apache/incubator-seata/issues/6454
    //这里又说不是bug,推荐放到实现类中,且后续放到接口上的函数参数注解的用法,会被废除 https://github.com/apache/incubator-seata/issues/6235#issuecomment-1876397212
    //处理幂等
    @Override
    public boolean save_commit(@BusinessActionContextParameter(paramName = "params")Trade entity) {

        //幂等
        lambdaUpdate()
                .eq(Trade::getSession_id, entity.getSession_id())
                .eq(Trade::getState, 0)
                .set(Trade::getState, 1).update();
        //更新失败,表示已被更新过了,直接返回成功了

        return true;
    }

    //处理幂等
    @Override
    public boolean save_rollback(@BusinessActionContextParameter(paramName = "params")Trade entity) {

        //todo 作为一个优化,可以插入state的以外的默认值,而不必插入原来的值
        entity.setState(2);
        try{
            //插入成功,则是空回滚;
            super.save(entity);
        }catch (DuplicateKeyException e){
            //幂等或正常回滚
            log.info("{}",e);
            var state=lambdaQuery().eq(Trade::getSession_id, entity.getSession_id()).one().getState();
            if(state==0){//正常回滚
                if(lambdaUpdate().eq(Trade::getSession_id, entity.getSession_id()).set(Trade::getState,2).update()) {
                    return true;
                }
                log.error("回滚失败,请检查数据库一致性");
                return true;
            }
        }
        return true;

    }
}




